package com.hd123.rumba.gwt.widget2.client.grid.renderer;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.ListenerWrapper;
import com.google.gwt.user.client.ui.SourcesClickEvents;
import com.google.gwt.user.client.ui.Widget;

/**
 * 多个控件渲染器
 * <p>
 * <li>多个控件横向排列。
 * <li>每个控件必须实现HasText接口，用来设置和显示控件的标题。
 * <li>
 * 如果控件实现了SourcesClickEvents接口，
 * 则会在控件被点击是触发所属RGrid的RGridClickListener #onClick事件
 * <li>provider提供的数据应为包含控件标题的字符串数组
 * 
 * @author LiQi
 * 
 */
@SuppressWarnings("deprecation")
public abstract class RWidgetsRenderer extends FlexTable implements RCellRenderer,
    SourcesClickEvents {

  /** 控件标题 */
  private String[] captions;

  public RWidgetsRenderer() {
    setCellPadding(0);
    setCellSpacing(0);
  }

  public Object getValue() {
    return captions;
  }

  public void setValue(Object value) {
    if (value instanceof String[]) {
      captions = (String[]) value;
    } else {
      captions = null;
    }
    rebuildWidgets();
  }

  /**
   * 创建一个新的控件，此控件应是一个实现了HasText接口的Widget
   * 
   * @return
   */
  public abstract Widget createWidget();

  /**
   * 构造控件，若相应位置的控件已存在，则修改其标题
   * 
   */
  private void rebuildWidgets() {
    if (captions == null) {
      // 清除已存在的控件
      if (getRowCount() > 0)
        for (int col = 0; col < getCellCount(0); col++)
          clearCell(0, col);
      return;
    }

    for (int i = 0; i < captions.length; i++) {
      if (isCellPresent(0, i) && getWidget(0, i) != null) {
        // 修改标题
        ((HasText) getWidget(0, i)).setText(captions[i]);
      } else {
        // 创建控件
        Widget widget = createWidget();
        if (!(widget instanceof HasText))
          throw new RuntimeException("createWidget的返回值应实现HasText接口");
        ((HasText) widget).setText(captions[i]);

        setWidget(0, i, widget);

        // 设置控件之间的间距
        if (i > 0) {
          DOM.setStyleAttribute(getCellFormatter().getElement(0, i), "paddingLeft", "5px");
        }
      }
    }

    // 删除多余的控件
    if (getRowCount() > 0 && captions.length < getCellCount(0)) {
      for (int col = captions.length; col < getCellCount(0); col++) {
        clearCell(0, col);
      }
    }
  }

  /**
   * 根据点击事件查找被点击的控件
   * 
   * @param event
   * @return
   */
  Widget getWidgetForEvent(ClickEvent event) {
    Cell cell = getCellForEvent(event);
    return getWidget(cell.getRowIndex(), cell.getCellIndex());
  }

  /**
   * @deprecated 请用{@link #addClickHandler}代替
   */
  @Deprecated
  public void addClickListener(ClickListener listener) {
    ListenerWrapper.WrappedClickListener.add(this, listener);
  }

  /**
   * @deprecated 请用{@link #addClickHandler}返回的
   *             {@link HandlerRegistration#removeHandler}代替
   */
  @Deprecated
  public void removeClickListener(ClickListener listener) {
    ListenerWrapper.WrappedClickListener.remove(this, listener);
  }

}
